home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacTech 1 to 12
/
MacTech-vol-1-12.toast
/
Reference
/
the cmsp digests ('94-'97)
/
csmp digest Vol 3 No 017
< prev
next >
Wrap
Internet Message Format
|
1997-05-06
|
74KB
From: pottier@clipper.ens.fr (Francois Pottier)
Subject: csmp-digest-v3-017
Date: Wed, 20 Apr 94 13:09:01 MET DST
C.S.M.P. Digest Wed, 20 Apr 94 Volume 3 : Issue 17
Today's Topics:
'aete' and AppleScript
Help on recursive read of directory catalog..?
How can I display TIFF?
Inverting a button in a dialog
Looking for styled TE replacement?
Mounting AFPServer volume...
PPC ThreadManager w-CodeWarrior
RJW: Retrieving application name from OSType Creator
Range of OSErr's for private use?
Simple Q: Assigning char * to char []. How?
[Q] Validity of a memory address
textedit bounds
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.
Also, the digests are available to WAIS users as comp.sys.mac.programmer.src.
-------------------------------------------------------
>From "Jared M. Oberhaus" <oberhaus+@CMU.EDU>
Subject: 'aete' and AppleScript
Date: Tue, 29 Mar 1994 03:54:34 -0500
Organization: Senior, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA
OK, I think I've figured out that the aete resource is the Dictionary
for translating raw AppleEvent formats into plain English-like commands.
But, where is the Template resource for ResEdit, so I can create and
modify this resource?
And if it doesn't exist yet, how do all you other guys do it? Not the
hard way, I hope...
Help!!
ps-I saw the demo of Resorcerer and noticed that it supports aete
resources, and looked around, and I supposed I could figure out how to
do an aete resoure by looking at the hex offsets, etc., but I don't
exactly feel like doing that!
pps-If you could, when you respond, could you respond to All (that is,
put me on the adressee list) instead of just Readers, that way, it'll be
easier than looking through five hundred messages every day... Thanks!
- ---------------------------------------------------------------------------
Jared M. Oberhaus oberhaus+@CMU.EDU
Electrical and Computer Engineering Class of 1994
Carnegie Mellon University
- ---------------------------------------------------------------------------
"We are upping our standards,...so up yours."
- Pat Paulsen for President, 1988
+++++++++++++++++++++++++++
>From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
Date: 30 Mar 94 11:19:56 +1300
Organization: University of Waikato, Hamilton, New Zealand
In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
> OK, I think I've figured out that the aete resource is the Dictionary
> for translating raw AppleEvent formats into plain English-like commands.
>
> But, where is the Template resource for ResEdit, so I can create and
> modify this resource?
I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
doesn't seem to be entirely reliable in its support for templates, and I've
hit problems trying to use it to open some aete resources.
Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
decompile the aete into source form. If I don't, then the Script Editor's
"Open Dictionary" command suffices.
Lawrence D'Oliveiro fone: +64-7-856-2889
Info & Tech Services Division fax: +64-7-838-4066
University of Waikato electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
My hard disk is a Mightgrosoft-free zone.
+++++++++++++++++++++++++++
>From knut.mork@admin.uio.no (Knut Mork)
Date: Wed, 30 Mar 1994 10:16:28 +0200
Organization: UniNett
In article <1994Mar30.111959.27070@waikato.ac.nz>, ldo@waikato.ac.nz
(Lawrence D'Oliveiro, Waikato University) wrote:
> In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus" <oberhaus+@CMU.EDU> writes:
> > OK, I think I've figured out that the aete resource is the Dictionary
> > for translating raw AppleEvent formats into plain English-like commands.
> >
> > But, where is the Template resource for ResEdit, so I can create and
> > modify this resource?
>
> I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
> doesn't seem to be entirely reliable in its support for templates, and I've
> hit problems trying to use it to open some aete resources.
>
> Generally, if I want to know details of event IDs etc, I use MPW's DeRez to
> decompile the aete into source form. If I don't, then the Script Editor's
> "Open Dictionary" command suffices.
The AppleScript developer CD also has a HyperCard stack for constructing
aete resources, which is extremely useful. It has Rez templates for MPW,
but those didn't work.. they compiled 'aete' resources which were invalid,
at least for me. Anybody else have this problem?
--Knut
+++++++++++++++++++++++++++
>From mlanett@netcom.com (Mark Lanett)
Date: Wed, 30 Mar 1994 08:14:12 GMT
Organization: Etch-a-Sketch Analysis and Design
ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
>doesn't seem to be entirely reliable in its support for templates, and I've
>hit problems trying to use it to open some aete resources.
I don't have the AS toolkit, so when I felt like doing stuff with scripting
I had to figure out the format of the aete resource myself, and...
It looks like it can't be handled by ResEdit. Apparently all the "direct"
types like shorts and longs are word-aligned, but strings are not. There's no
way to create a template which handles word-alignment in ResEdit, alas, and
since the strings *aren't* aligned you can't make a template that works by
specifying ESTR instead of PSTR.
>...the Script Editor's
>"Open Dictionary" command suffices.
Never even thought of that one. Oh well, Sucks to be me.
>My hard disk is a Mightgrosoft-free zone.
I love MS products. *My* HD is a Symantec-free zone.
--
Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
+++++++++++++++++++++++++++
>From alldritt@mdd.comm.mot.com (Mark Alldritt)
Date: 30 Mar 1994 08:31:00 -0800
Organization: Motorola - Wireless Data Group; Richmond, BC
In <mlanettCnGxJo.Fov@netcom.com> mlanett@netcom.com (Mark Lanett) writes:
>ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>>I think I found a copy on the AppleScript developer CD. Trouble is, ResEdit
>>doesn't seem to be entirely reliable in its support for templates, and I've
>>hit problems trying to use it to open some aete resources.
>I don't have the AS toolkit, so when I felt like doing stuff with scripting
>I had to figure out the format of the aete resource myself, and...
>It looks like it can't be handled by ResEdit. Apparently all the "direct"
>types like shorts and longs are word-aligned, but strings are not. There's no
>way to create a template which handles word-alignment in ResEdit, alas, and
>since the strings *aren't* aligned you can't make a template that works by
>specifying ESTR instead of PSTR.
The AppleScript developer CD contains a TMPL resource for editing aete
resources which works reasonably well. The problem is that TMPL layouts
can only handle a limited number of fields. Application aete resources are
generally too large to be edited using the aete TMPL.
Another alternative is the aete editing Hypercard stack Apple provides on
the AppleScript CD and (I think) on the Develop Bookmark CD.
However, if your just interested in know what events and classes a application
understands then the Script Editor's dictionary window is your best bet.
-Mark
+++++++++++++++++++++++++++
>From lai@apple.com (Ed Lai)
Date: 5 Apr 1994 17:04:19 GMT
Organization: Apple
In article <AhZyn_y00iV4E0fEpd@andrew.cmu.edu>, "Jared M. Oberhaus"
<oberhaus+@CMU.EDU> wrote:
> OK, I think I've figured out that the aete resource is the Dictionary
> for translating raw AppleEvent formats into plain English-like commands.
>
> But, where is the Template resource for ResEdit, so I can create and
> modify this resource?
>
It should be on the developer CD. You should also find a copy in
from ftp.apple.com in /pub/appleevents, although that may not be the
latest copy. The problem is that ResEdit template editing probably
uses the dialog manager and there can only be a limited number of
item in the dialog, any decent size aete would reach the limit so
for practical purpose it is useless for aete unless the aete is
are very simple like those in an OSAX.
You should be able to find the HyperCard aete editor stack in the
same place.
> And if it doesn't exist yet, how do all you other guys do it? Not the
> hard way, I hope...
>
> Help!!
>
> ps-I saw the demo of Resorcerer and noticed that it supports aete
> resources, and looked around, and I supposed I could figure out how to
> do an aete resoure by looking at the hex offsets, etc., but I don't
> exactly feel like doing that!
I hear that Resorcerer is very good at editing aete resource, this is
certainly a solution for those who owns Resorcerer.
There is yet another solution. I have written an osax to translate
between resources and list using ResEdit template, and since aete is
a resource with ResEdit template. In theory you can use the osax
and generate aete resource using AppleScript. I have not tried it
for a long time, but I suspect it is very slow so may not be
practical except for smaller aete. The osax can be found in
ftp.apple.com in /pub/lai/osax/pgmTool.sit.hqx
--
/* Disclaimer: All statments and opinions expressed are my own */
/* Edmund K. Lai */
/* Apple Computer, MS303-3A */
/* 20525 Mariani Ave, */
/* Cupertino, CA 95014 */
/* (408)974-6272 */
zW@h9cOi
---------------------------
>From dsf5454@ritvax.isc.rit.edu
Subject: Help on recursive read of directory catalog..?
Date: Sun, 3 Apr 1994 16:59:38 GMT
Organization: Rochester Institute of Technology
Ok...basically, I have a crucial subroutine where I need to read a directory
tree below a specific subdirectory. However, I notice that I seem to be
crashing into the debugger with an error of #28 and somewhere around in a VBL
queue - stack and application heap collison. Therefore, I'm not sure how I
could efficiently code such a recursive call... suggestions or pointers,
anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
start from root folder.
I have a newer version that was re-written, but the principle is the same...
Roughly speaking, here's what it looks like at the moment..:
-Dan
Internet: dsf5454@ritvax.isc.rit.edu
BITNET/CREN: dsf5454@ritvax.BITNET
long RecursiveDirList (t, dirIDToSearch)
short t;
long dirIDToSearch;
{
short index = 1;
OSErr err;
long curLine;
do {
myCPB.fileParam.ioFDirIndex = index;
myCPB.fileParam.ioVRefNum = vRefNum;
myCPB.fileParam.ioDirID = dirIDToSearch;
myCPB.fileParam.ioNamePtr = (unsigned char *)fName;
err = PBGetCatInfo ((CInfoPBPtr)&myCPB, 0);
if (err == noErr)
{
if (((myCPB.fileParam.ioFlAttrib >> 4) & 0x01) == 1)
{
RecursiveDirList(t+1,myCPB.fileParam.ioDirID);
err = 0;
/* It's a directory; we want to go deeper into
the subdirectories */
}
else
{
/* it's a file */
}
}
index++;
} while ((err != fnfErr) && (err == noErr));
}
+++++++++++++++++++++++++++
>From allon@intercon.com (Allon Stern)
Date: Tue, 5 Apr 1994 03:09:18 -0400
Organization: InterCon Systems Corporation, Herndon VA.
In article <1994Apr3.165938.3952@ultb.isc.rit.edu>,
dsf5454@ritvax.isc.rit.edu writes:
>
> Ok...basically, I have a crucial subroutine where I need to read a
> directory tree below a specific subdirectory. However, I notice that I
> seem to be crashing into the debugger with an error of #28 and
> somewhere around in a VBL queue - stack and application heap collison.
> Therefore, I'm not sure how I could efficiently code such a recursive
> call... suggestions or pointers, anybody? I'm calling it with
> RecursiveDirList(1, 2L); in main to tell it to start from root folder.
>
> I have a newer version that was re-written, but the principle is the
> same...
> Roughly speaking, here's what it looks like at the moment..:
>
> -Dan
> Internet: dsf5454@ritvax.isc.rit.edu
> BITNET/CREN: dsf5454@ritvax.BITNET
It seems to me that you could probably do this non-recusively.
Keep in mind that you will end up using stack space for each recursive call,
and also that PBGetCatInfo and the file manager may also use some stack
space.
Rather than using the stack to store where you were, you could build your own
stack structure, say, using an array. This would minimize stack usage, and
would also store the same information much more efficiently. If it is a
transient thing (i.e. you use a bunch of storage for a short time, then would
release it), you could use temporary memory for it. You could also use a
dynamic array, and if you run out of room in your own heap, you could transfer
the contents to a handle in temporary memory space.
You could try increasing the memory requested for the program, but I think
the best thing in this case is to find a non-recursive way to do it.
--
Allon
| Allon Stern | 703-709-5557 | Ring around the Internet |
| allon@intercon.com | KE4FYL | A packet with a bit not set |
+--------------------+--------------+ ENQ ACK ENQ ACK |
| All opinions above are my own. | We all go down! |
|------------------------------------------------------------------|
+++++++++++++++++++++++++++
>From d88-jwa@mumrik.nada.kth.se (Jon Wätte)
Date: 5 Apr 1994 08:13:09 GMT
Organization: The Royal Institute of Technology
In <9404050309.AA18685@hazmat.intercon.com> allon@intercon.com (Allon Stern) writes:
>> Ok...basically, I have a crucial subroutine where I need to read a
>> directory tree below a specific subdirectory. However, I notice that I
>> seem to be crashing into the debugger with an error of #28 and
>> somewhere around in a VBL queue - stack and application heap collison.
>It seems to me that you could probably do this non-recusively.
>Keep in mind that you will end up using stack space for each recursive call,
>and also that PBGetCatInfo and the file manager may also use some stack
>space.
Yeah, but PBGetCatInfo will give the stack space back when it's done.
(It should be called as PBGetCatInfoSync() by the way, or maybe
PBGetCatInfoAsync ( ) ; while ( rec . ioResult == 1 ) Yield ( ) ;)
Anyway, his routine only ate 4+4+4+4+4+4+4 bytes per recursion
(2 int arguments, a6 link, return address, three int locals, given
4-byte ints)
At 28 bytes per recursion, you need > 1000 folders deep structures
to hit any real problems, unless you have MASSIVE parameter blocks
and Str255s on the stack higher up. (Putting Str255s on the stack
is a BAD idea btw)
What he could do is call StackSpace() (or whatever) before each
recursive call, and call Debugger() if it goes below a K or so.
Most probably, however, he's having some other bug which is causing
the problem.
--
-- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
What we need is a good GNU [...] licence manager implementation.
-- Raphael Manfredi
+++++++++++++++++++++++++++
>From jumplong@aol.com (Jump Long)
Date: 5 Apr 1994 12:44:02 -0400
Organization: America Online, Inc. (1-800-827-6364)
In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
writes:
> Ok...basically, I have a crucial subroutine where I need to read a directory
> tree below a specific subdirectory. However, I notice that I seem to be
> crashing into the debugger with an error of #28 and somewhere around in a VBL
> queue - stack and application heap collison. Therefore, I'm not sure how I
> could efficiently code such a recursive call... suggestions or pointers,
> anybody? I'm calling it with RecursiveDirList(1, 2L); in main to tell it to
> start from root folder.
You're using too much stack in your recursive routine - either that, of you
don't have much stack when you start your recursive routine.
You can check the stack space before you start with the StackSpace function.
If that isn't your problem, then you might want to look at one of the recursive
routines I put in DTS's MoreFiles File Manager sample code. In particular, the
routines in DirectoryCopy.c show how you can use very little stack space per
level in a recursive routine that enumerates a directory structure on a
Macintosh disk volume.
The code in MoreFiles is based on the ideas presented in the Technical Note "
+++++++++++++++++++++++++++
>From jumplong@aol.com (Jump Long)
Date: 5 Apr 1994 12:45:03 -0400
Organization: America Online, Inc. (1-800-827-6364)
In article <1994Apr3.165938.3952@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu
writes:
Ooops, hit the send button too soon... starting where I left off.
on ideas presented in the Technical Note "FL 31 - Searching Volumes-Solutions
and Problems".
Hope that helps.
Jim Luther
Apple DTS
---------------------------
>From jbell@garnet.berkeley.edu (John E. Bell)
Subject: How can I display TIFF?
Date: 22 Mar 1994 11:07:24 GMT
Organization: University of California, Berkeley
How can I display a TIFF file in my program? Are there library routines
somewhere?
Thanks - John E. Bell
+++++++++++++++++++++++++++
>From mssmith@afterlife.ncsc.mil (M. Scott Smith)
Date: Tue, 22 Mar 1994 12:18:47 GMT
Organization: The Great Beyond
In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E. Bell) writes:
>
>How can I display a TIFF file in my program? Are there library routines
>somewhere?
>
>Thanks - John E. Bell
John,
There are some samples floating about that show how to read the TIFF
format. The TIFF format is kind of an ugly thing to read; it takes a lot
of work. It's designed to be a very flexible file format, so each TIFF
file starts out with a number of "tags" which can contain everything from
the expected width and height of the image, to the resolution, even comments
and tags/fields which are specific to certain applications.
I guess in order to claim that your program can read TIFF, you need to
intelligently read a certain number of these tags, and you can ignore the
rest.
The tags will give you information like offsets for finding the actual
data, etc.
Really kind of yechy. But, alas: if I remember correctly, NIH Image,
a program which you can find at the usual FTP sites, reads color TIFF
images. The only problem is that it's written in Pascal. (That may
not be a problem for some people.) You can probably easily translate it
to C.
I've written black and white TIFF-reading code (not color), and I
suppose I might some day spruce that up to serve as an example. (Right now,
I think I'd be embarassed to claim credit for it. It does read files
quickly though.)
What I'd like is a nice C++ library that lets you save/read PixMaps
to/from a multitude of file formats, such as PICT, TIFF, PostScript,
and the like. I don't think such a thing exists (anyone know??), so
it seems whenever you want to write a program with these capabilities,
you need to re-invent the wheel.
Maybe people could get together and build this library; between us,
I'm sure we have all of the capability.
Anyway, good luck with the TIFF reading. (Trivia: TIFF stands for
Tagged Image File Format.)
- Scott
- -
M. Scott Smith (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
Mac developer. Student. Not a member of the Michael Bolton fan club.
+++++++++++++++++++++++++++
>From perm@csd.uu.se (Per Mildner)
Date: 22 Mar 1994 16:04:36 GMT
Organization: Computing Science Dept.,Uppsala University, Sweden
I recommend looking for LIBTIFF with Archie, it reads and writes
various tiff formats. My only problem with that is that I know an
application (Optix by Blueridge) that unpacks CCITT Group IV (fax)
very much faster than the seemingly optimized LIBTIFF code (on a
Quadra 700).
Regards,
--
Per Mildner Per.Mildner@CSD.UU.SE
Computing Science Dept. tel: +46 18 181049
Uppsala University, Sweden fax: +46 18 511925
+++++++++++++++++++++++++++
>From markhanrek@aol.com (MarkHanrek)
Date: 22 Mar 1994 20:45:07 -0500
Organization: America Online, Inc. (1-800-827-6364)
Yes, there is some TIFF source code available from a variety of places.
The place to start, though, is the Aldus Developer Desk, which is on
CompuServe, from which you will be able to download the current TIFF Level 6.0
specification, example source code (for level 5), and some TIFF pictures which
are good to use for testing.
Or you could contact Aldus directly. Perhaps there is Internet access to them
Mark Hanrek
+++++++++++++++++++++++++++
>From kenlong@netcom.com (Ken Long)
Date: Wed, 23 Mar 1994 02:51:35 GMT
Organization: NETCOM On-line Communication Services (408 241-9760 guest)
There's some TIFF reader code on AOL. Next time I log on I'll get a
description of it for you. Seems like I saw some elsewhere, too. i'll
check it out.
-Ken-
+++++++++++++++++++++++++++
>From xinwei@otter.Stanford.EDU (Sha Xin Wei)
Date: 5 Apr 1994 21:39:26 GMT
Organization: Stanford University
M. Scott Smith writes
> In article <2mmjhc$sno@agate.berkeley.edu> jbell@garnet.berkeley.edu (John E.
Bell) writes:
> >
> >How can I display a TIFF file in my program? Are there library routines
> >somewhere?
> >
> >Thanks - John E. Bell
>
> John,
>
> There are some samples floating about that show how to read the TIFF
> format.> Maybe people could get together and build this library; between
us,
> I'm sure we have all of the capability.
>
> Anyway, good luck with the TIFF reading. (Trivia: TIFF stands for
> Tagged Image File Format.)
>
> - Scott
>
> ---
> M. Scott Smith (mssmith@afterlife.ncsc.mil || umsmith@mcs.drexel.edu)
By the way, in the unix world there's a whole wonderful library named pbmplus
by Jef Pozkaner, written in C, which is in the public domain. It provides a
slew of tools for conversion between 12-40 different graphics formats
(depending on how you count) -- PICT, TIFF, PS, GIF, etc., and much more: color
histogram, diffusion, quatization, scaling, rotation, palette remaps, even
general convolution given a user-supplied kernel. All in public domain.
PixelMagician, a NeXTSTEP application has extended pbmplus to handle pixmaps
with alpha channel, and a few more formats.
If anyone has compiled this under MPW or ThinkC, could they please publish it?
Thanks.
Sha Xin Wei
Stanford University
---------------------------
>From Vik_Rubenfeld@lamg.com (Vik Rubenfeld)
Subject: Inverting a button in a dialog
Date: 05 Apr 1994 00:21:14 -0000
Organization: (none)
I've set up a filter procedure that returns the item number of the cancel
button if the user hits the escape key. This lets the user dismiss the dialog
from the keyboard, without using the mouse. It works great. However, it does
not invert the cancel button before dismissing the dialog.
So, could someone upload some sample code that highlights (inverses) a
standard dialog button? Thanks.
+++++++++++++++++++++++++++
>From t-gaul@i-link.com (Troy Gaul)
Date: Tue, 05 Apr 1994 10:48:58 -0500
Organization: I-Link, Ltd.
In article <101974014.48568985@lamgnet.lamg.com>, Vik_Rubenfeld@lamg.com
(Vik Rubenfeld) wrote:
> I've set up a filter procedure that returns the item number of the cancel
> button if the user hits the escape key. This lets the user dismiss the dialog
> from the keyboard, without using the mouse. It works great. However, it does
> not invert the cancel button before dismissing the dialog.
>
> So, could someone upload some sample code that highlights (inverses) a
> standard dialog button? Thanks.
ControlHandle
GetControlItemHandle(DialogPtr dlog, short item) {
short iKind;
Handle iHandle;
Rect iRect;
GetDItem(dlog, item, &iKind, &iHandle, &iRect);
switch (iKind & ~itemDisable) {
case btnCtrl + ctrlItem:
case chkCtrl + ctrlItem:
case radCtrl + ctrlItem:
case resCtrl + ctrlItem:
return (ControlHandle) iHandle;
}
return nil;
}
void
FlashDItem(DialogPtr dlog, short item) {
long ignored;
ControlHandle button;
button = GetControlItemHandle(dlog, item);
if (button != nil && (**button).contrlHilite != 255) {
HiliteControl(button, 1);
Delay(8, &ignored); // the Apple prescribed period of time
HiliteControl(button, 0);
}
}
Of course, to flash the cancel button, you just call:
FlashDItem(dlog, cancel);
_troy
//////// //////___Troy Gaul_________________________t-gaul@i-link.com__ //
// // I-Link, Ltd. ; West Des Moines, Iowa //
// // // "Iungo ergo sum." (I-Link, therefore I am.) //
// //////________________________________________________________ //
+++++++++++++++++++++++++++
>From charlesworth@andyne.on.ca (Dave Charlesworth)
Date: Tue, 5 Apr 1994 22:15:45 GMT
Organization: Andyne Computing
I don't have sample code handy but you'll find it really simple to
write. Here's the basic outline:
1. Get the Cancel button item from the dialog.
2. Coerce it to a control.
3. Tell the control to highlight.
4. Wait long enough for the user to see it.
5. Go on with dismissing your dialog...
.../dave Dave Charlesworth
---------------------------
>From RobTerrell@aol.com (Rob Terrell)
Subject: Looking for styled TE replacement?
Date: 4 Apr 1994 17:55:08 GMT
Organization: Jecta Development Corp.
A few weeks back someone mentioned a styled text edit replacement
called "WASTE". The poster claimed it would do styles as well as >32K
of text.
I've never heard of it, nor has archie. Any ideas?
Thanks,
Rob
Software Designs Unlimited
+++++++++++++++++++++++++++
>From mlanett@netcom.com (Mark Lanett)
Date: Tue, 5 Apr 1994 02:30:27 GMT
Organization: Etch-a-Sketch Analysis and Design
RobTerrell@aol.com (Rob Terrell) writes:
>A few weeks back someone mentioned a styled text edit replacement
>called "WASTE". The poster claimed it would do styles as well as >32K
>of text.
Host: ghost.dsi.unimi.it (149.132.1.2)
Path: pub2/papers/piovanel/
--
Mark Lanett "...a bajillion brilliant Jobsian lithium licks"
---------------------------
>From rdm4@acpub.duke.edu (RYAN MARTELL)
Subject: Mounting AFPServer volume...
Date: 5 Apr 1994 21:26:42 GMT
Organization: Duke University, Durham, N.C.
Does anyone have any sample code showing how to mount a volume from an
AFPServer remotely? I already have the address of the Server, and
figure I need to use AFPCommand, but I don't know how to send the
proper name/password verification data- or is there just a standard
call to do all of that for you? (Essentially, I am trying to write
something that acts as the chooser for you..)
Any help would be appreciated, please reply by email.
-Ryan Martell
+++++++++++++++++++++++++++
>From jumplong@aol.com (Jump Long)
Date: 5 Apr 1994 23:55:02 -0400
Organization: America Online, Inc. (1-800-827-6364)
In article <2nsl2i$p38@news.duke.edu>, rdm4@acpub.duke.edu (RYAN MARTELL)
writes:
> Does anyone have any sample code showing how to mount a volume from an
> AFPServer remotely? I already have the address of the Server, and
> figure I need to use AFPCommand, but I don't know how to send the
> proper name/password verification data- or is there just a standard
> call to do all of that for you? (Essentially, I am trying to write
> something that acts as the chooser for you..)
There's two ways to do this so that the volume is mounted by the File Manager
(you probably don't want to mount the volume using AFP commands because the
File Manager won't know about the volume if mounted that way).
The first method is to use the Alias Manager. Create a new alias record using
the NewAliasMinimalFromFullPath function. Then, resolve the alias with the
ResolveAlias function. The Alias Manager will take care of the user interface
for you.
The second way is to use the File Manager's PBVolumeMount function. You'll need
to build an AFP VolumeMountInfo record to pass to PBVolumeMount. The
BuildAFPVolMountInfo function in the Apple DTS MoreFiles sample code will do
that for you. MoreFiles also includes a high level versions of the VolumeMount
related calls if you don't like using parameter blocks.
- Jim Luther
---------------------------
>From Frank Price <wprice@jarthur.claremont.edu>
Subject: PPC ThreadManager w-CodeWarrior
Date: 5 Apr 1994 16:38:15 GMT
Organization: Pomona College
Has anybody managed to get the ThreadManager 2.0d7 release running native
on the PowerPC using CodeWarrior? All I get is crashes on NewThread which
somewhat limits what one can do. Other simple calls like GetCurrentThread
seem to work fine. Haven't tried this with MPW yet, but I don't imagine it
would be any different (but if it wasn't different, how could they have
released this??) Compiling the same code for 68k runs fine. No, I'm not
trying to make preemptive threads, and I believe it would return an error
even if I had. Also, did anyone notice that the Threads.h header file
doesn't even compile? An excess comma has to be removed from inside an
enum. I get the feeling this went out the door a little too quickly.
-Frank
_______________________________________________________________________
| Frank Price | wprice@jarthur.claremont.edu |
|_______________|______________________________________________________|
+++++++++++++++++++++++++++
>From REDDEN@applelink.apple.com (Kevin Redden)
Date: Tue, 5 Apr 1994 21:07:53 GMT
Organization: Apple Computer
In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
<wprice@jarthur.claremont.edu> wrote:
> Has anybody managed to get the ThreadManager 2.0d7 release running native
> on the PowerPC using CodeWarrior? All I get is crashes on NewThread which
> somewhat limits what one can do. Other simple calls like GetCurrentThread
> seem to work fine. Haven't tried this with MPW yet, but I don't imagine it
> would be any different (but if it wasn't different, how could they have
> released this??) Compiling the same code for 68k runs fine. No, I'm not
> trying to make preemptive threads, and I believe it would return an error
> even if I had. Also, did anyone notice that the Threads.h header file
> doesn't even compile? An excess comma has to be removed from inside an
> enum. I get the feeling this went out the door a little too quickly.
>
I had some code that I got working with it quite a while ago (I'm not
positive that it was 2.0d7 but I think so because I got the same comma
error), but I never tried it with CodeWarrier, just Apples SDK for PowerPC.
The comma compiles straight through with CFront and I believe that PPCC
only flags it when -strict on is specified. I did bring the comma problem
up with one of the engineers that works on the Threads package but it was
already too late. Hopefully in the next versionÉ
Kevin
Tech Lead, Macintosh On RISC SDK 2.0
+++++++++++++++++++++++++++
>From bpost@apple.com (Brad Post)
Date: Wed, 6 Apr 1994 01:44:05 GMT
Organization: Apple Computer
In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
<wprice@jarthur.claremont.edu> wrote:
>
> Has anybody managed to get the ThreadManager 2.0d7 release running native
> on the PowerPC using CodeWarrior? All I get is crashes on NewThread which
> somewhat limits what one can do. Other simple calls like GetCurrentThread
> seem to work fine. Haven't tried this with MPW yet, but I don't imagine it
> would be any different (but if it wasn't different, how could they have
> released this??) Compiling the same code for 68k runs fine. No, I'm not
> trying to make preemptive threads, and I believe it would return an error
> even if I had. Also, did anyone notice that the Threads.h header file
> doesn't even compile? An excess comma has to be removed from inside an
> enum. I get the feeling this went out the door a little too quickly.
Okay this is a simple problem to fix (crashing that is). The problem is
that you are most likely using the Voodoo Monkey Debugger Init. It doesn't
know about the native thread manager, so it's trying to do some gross stuff
that it shouldn't be doing. Remove it and you should work just fine. As
for the comma, it slipped out, and it should be fixed in the latest/next
release (or it's an exercise for the programmer !-)
Brad 'SMMFD' Post
+++++++++++++++++++++++++++
>From jwbaxter@olympus.net (John W. Baxter)
Date: Tue, 05 Apr 1994 17:46:04 -0700
Organization: Internet for the Olympic Peninsula
In article <2ns45n$ht9@jaws.cs.hmc.edu>, Frank Price
<wprice@jarthur.claremont.edu> wrote:
> Has anybody managed to get the ThreadManager 2.0d7 release running native
> on the PowerPC using CodeWarrior? All I get is crashes on NewThread which
> somewhat limits what one can do.
You might have better luck with the ThreadManager 2.0 (no qualification)
which appeared on the April Developer CD. I don't believe this one is the
last word in Thread Managers, either, though.
--
John Baxter Port Ludlow, WA, USA [West shore, Puget Sound]
jwbaxter@pt.olympus.net
+++++++++++++++++++++++++++
>From Frank Price <wprice@jarthur.claremont.edu>
Date: 6 Apr 1994 17:04:27 GMT
Organization: Pomona College
In article <bpost-050494183834@bsp.apple.com> Brad Post, bpost@apple.com
writes:
>Okay this is a simple problem to fix (crashing that is). The problem is
>that you are most likely using the Voodoo Monkey Debugger Init. It doesn't
>know about the native thread manager, so it's trying to do some gross stuff
>that it shouldn't be doing. Remove it and you should work just fine. As
>for the comma, it slipped out, and it should be fixed in the latest/next
>release (or it's an exercise for the programmer !-)
I wasn't and haven't ever used Voodoo Monkey. I also took the suggestions
of others to get the 2.0 release off the April CD instead of 2.0d7. Same
problem. Compiling the simple NativeThreads app linking with the xcoff
file, it always crashes with an "access fault exception" at NewThread.
Would appreciate it if someone could try this out to confirm what I'm
saying. I'm using DR2 of CodeWarrior. And again, everything still works
fine for the same code in 68k on the same machine.
-Frank
_______________________________________________________________________
| Frank Price | wprice@jarthur.claremont.edu |
|_______________|______________________________________________________|
---------------------------
>From piper@char.vnet.net (John Wash)
Subject: RJW: Retrieving application name from OSType Creator
Date: 31 Mar 1994 17:04:19 -0500
Organization: Vnet Internet Access, Inc. - Charlotte, NC. (704) 374-0779
Hi. This is done in the Finder, so I'm sure there's a simple way to do
it. I have a document reference stored in a database. I know it's
four-character Creator. How do I resolve that Creator into a path to the
application?
I've looked through my old Inside Macs. It seems to me that it should be
just a Toolbox call, but I can't seem to find it.
E-mail or followup messages appreciated.
Thanks!
John Wash
piper@vnet.net
--
-
John Wash piper@vnet.net
Wee Doggie Musical Instruments 919-851-4620
"Bagpipes are the missing link between music and noise." --Gordon Mooney
+++++++++++++++++++++++++++
>From jumplong@aol.com (Jump Long)
Date: 5 Apr 1994 12:34:09 -0400
Organization: America Online, Inc. (1-800-827-6364)
In article <2nfhd3$1b3@char.vnet.net>, piper@char.vnet.net (John Wash) writes:
> How do I resolve that Creator into a path to the
> application?
I'd start by using the Process Manager to look through the list of open
processes to see if the application is already running.
If the process isn't running, then use the Desktop Manager's PBDTGetAPPL
function on the mounted volumes to try to locate the application. You'll want
to start with the volume the file with the creator is on and if you don't find
a match there, go on to the boot volume, local volumes, and then last, remote
volumes. So, until you find a match, here's the steps you'll need to take:
1) Make sure the volume supports the Desktop Manager using PBHGetVolParms
(check for the bHasDesktopMgr attribute bit).
2) Open the desktop database (i.e., get the dtRefNum needed to make calls to
the Desktop Manager) on that volume using PBDTOpenInform. If PBDTOpenInform
fails with a paramErr, then try again using PBDTGetPath to open the desktop
database.
3) Call PBDTGetAPPL using the creator of the application you want to find.
Start with ioIndex = 0 to get the newest match in the desktop database, check
to make sure the application match is really there and if not, increment the
index, call PBDTGetAPPL again to get the next match. If you get to the end of
the match list on the volume (with an afpItemNotFound error), try the next
volume.
OK, so what if you don't find a match using the Desktop Manager, then you'll
probably want to try any volumes that *don't* support the Desktop Manager (and
thus, have the old Desktop resource file). There's more than one way to do
this. You could simply search the volume (using PBCatSearch) for a file with
the creator and a file type of 'APPL'. Or, if you really wanted, you could use
the Desktop file on the disk volume. Since the Finder already has the Desktop
file open and you won't be able to open it with the Resource Manager, you'll
need to make a temporary copy of the Desktop file. You can use the FileCopy
function in DTS's MoreFiles File Manager sample code to make the copy of the
Desktop file. Then you can open it up with the Resource Manager and use the
'APPL' resourced to attempt to find a matching application. The Technical Note
"Resources Contained in the Desktop File" describes the resources you'll find
in the Desktop file and in particular, the 'APPL' resources.
So, what else can you do if none of these things finds an application match?
You could search each mounted volume for for a file with the creator and a file
type of 'APPL'. The CreatorTypeFileSearch function in the MoreFiles sample
uses CatSearch to quickly search a volume for a file specified by creator and
file type.
About the only thing you cannot do that the Finder does is look through the
Finder's open windows for a match.
- Jim Luther
---------------------------
>From stk@uropax.contrib.de (Stefan Kurth)
Subject: Range of OSErr's for private use?
Date: 5 Apr 1994 20:47:50 +0200
Organization: Contributed Software GbR
Almost every function that I write returns a value of type OSErr.
Sometimes it would be desirable to return a private error code of my
own, rather than one of the Apple ones. Is there a range of values
that I can safely use for my own #defines, without having to worry
whether Apple might use them for their system 9.0 implementation of
the espresso manager or something?
-Stefan
_____________________________________________________________________
Stefan Kurth Berlin, Germany stk@contrib.de
+++++++++++++++++++++++++++
>From gurgle@netcom.com (Pete Gontier)
Date: Wed, 6 Apr 1994 19:00:25 GMT
Organization: cellular
stk@uropax.contrib.de (Stefan Kurth) writes:
>Almost every function that I write returns a value of type OSErr.
>Sometimes it would be desirable to return a private error code of my
>own, rather than one of the Apple ones. Is there a range of values
>that I can safely use for my own #defines, without having to worry
>whether Apple might use them for their system 9.0 implementation of the
>espresso manager or something?
I was just thinking about this the other night, and my conclusion
was both yes and no.
It seems that the majority of error codes that Apple adds are negative.
They still have thousands left over, but they like to leave gaps in
between groups of error codes, so they might use positive codes in the
not-too-distant future. In fact, they already do use some of the lower
positive codes (for CTB calls). You could risk using relatively high
positive codes, but it probably wouldn't work in the long run and it
wouldn't even be guranateed to work in the short run.
One alternative I thought of is to simply return a 'long'. Since an
'OSErr' is nothing but a signed 16-bit quantity, you could use signed
values which don't fit in 16 bits for your error codes and return a
'long'. When you go to report the error, you could determine if the
value would have fit into an 'OSErr', and if it would have, that's what
it is, but if it wouldn't have, it must be one of your custom error
codes. The only problem with this is that if some of your routines
return an 'OSErr' and others return a 'CustomErr', C won't help you if
you forget and assign a 'CustomErr' to an 'OSErr'.
(A certain Swede who shall be nameless is likely to pop in here and
complain that not only should I really be advocating exceptions
instead of error codes but also that Pascal would be much better
for this scheme because it wouldn't allow you to screw up assigning
the function result. To which I say: yeah, and your mother wears
army boots! :-)
Of course, this is not what I personally do. Each of my modules has a
unique 8-bit "location code", and each module's functions which can
produce errors produce a 16-bit struct (fits nicely in a register)
which also contains a non-unique error code. Put the two codes together
and you have a description of which module caused the error and a a
description of what the error was which does not rely on 'OSErr'.
--
Pete Gontier, CTO, Integer Poet Software; gurgle@netcom.com
---------------------------
>From guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif)
Subject: Simple Q: Assigning char * to char []. How?
Date: Mon, 4 Apr 1994 21:27:46 GMT
Organization: Princeton University
This seems ridiculous: You should be able to assign a char * to
an array of characters. If you declare char a[10], a is a pointer
to the first of a contiguous group of 10 characters. Yet when I try
this on THINK C 6.0.1, it tells me I cannot assign to an array. If
I try to get around this with an assignment to &a[0], it tells
me that an lvalue is required. This is an error I have gotten
many times, and I do not know how to get around it. ANY help would
be greatly appreciated!! Thanks for the time. Guy
guyyalif@phoenix.princeton.edu
+++++++++++++++++++++++++++
>From zstern@adobe.com (Zalman Stern)
Date: Tue, 5 Apr 1994 06:32:24 GMT
Organization: Adobe Systems Incorporated
Guy Udassin Yalif writes
> This seems ridiculous: You should be able to assign a char * to
> an array of characters. If you declare char a[10], a is a pointer
> to the first of a contiguous group of 10 characters.
No, a represents an absolute address of ten characters of storage. There is
no storage allocated for a pointer (e.g. 4 bytes holding an address) which
points to the beginning of that ten byte array. Another way to put this is
that the declarations "extern char a[]" and "extern char *a" are very
different. The best way to see this is to look at the assembly code
generated for the following function:
extern char an_array[];
extern char *a_pointer;
int foo(void)
{
int return_value;
return_value = an_array[42];
return_value += a_pointer[42];
return return_value;
}
> Yet when I try
> this on THINK C 6.0.1, it tells me I cannot assign to an array. If
> I try to get around this with an assignment to &a[0], it tells
> me that an lvalue is required. This is an error I have gotten
> many times, and I do not know how to get around it. ANY help would
> be greatly appreciated!! Thanks for the time. Guy
The C language specification says that array values are automatically
converted to pointer values in most circumstances. It does not say they are
the same thing. Think-C is trying to tell you that you do not understand the
language. A good reading of the ANSI-C standard or other rigorous C
documentation might be in order.
--
Zalman Stern zalman@adobe.com (415) 962 3824
Adobe Systems, 1585 Charleston Rd., POB 7900, Mountain View, CA 94039-7900
"Do right, and risk consequences." Motto of Sam Houston (via Molly Ivins)
+++++++++++++++++++++++++++
>From d88-jwa@mumrik.nada.kth.se (Jon Wätte)
Date: 5 Apr 1994 08:00:58 GMT
Organization: The Royal Institute of Technology
In <1994Apr4.212746.24171@Princeton.EDU> guyyalif@tucson.Princeton.EDU (Guy Udassin Yalif) writes:
>This seems ridiculous: You should be able to assign a char * to
>an array of characters. If you declare char a[10], a is a pointer
No, you should not. It's right there in K&R 2nd ed (and, indeed,
1st ed as well)
That's because the array is a CONSTANT pointer to a slab of memory
that lives on the stack or in global space. You can't just move that
slab of memory; all you can do is copy stuff into or out of the
memory the array is "pointing to".
>me that an lvalue is required. This is an error I have gotten
>many times, and I do not know how to get around it. ANY help would
You can't. If you want to shove stuff into the actual array memory,
you should use strcpy() or memcpy() or possibly BlockMove(). If you
want a variable that can point at different arrays, you should use
a pointer variable and initialize it first.
--
-- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe --
What we need is a good GNU [...] licence manager implementation.
-- Raphael Manfredi
---------------------------
>From potterf@tartarus.uwa.edu.au (Felix Potter)
Subject: [Q] Validity of a memory address
Date: 28 Mar 1994 06:54:22 GMT
Organization: The University of Western Australia
How does one check that a pointer is valid? (Without dereferencing it and
possibly crashing the machine.) At the moment my definition for a pointer
that is at least _possibly_ OK is:
not null (ie. not equal to 0), and
even (ie. not divisble by 2), and
> ApplZone (low memory global), and
< ApplLimit (low memory global)
So if my pointer fails one of these conditions, then I know straight away
that something has gone wrong. Does anyone have any comments on either how
reasonable or, on the other hand, how totally stupid the above description is?
Any suggestions for better ways of going about it?
The reason I want to be able to check _quickly_ whether a pointer is valid
or not is that I am writing a few little 'wrapper' macros/functions to
go around the standard C malloc/calloc/realloc/free functions. I realise that
just about every man and his dog has done this before me, but hey, I'm
having fun :) One of the things I would like to be able to do is detect
heap corruption, and corruption of my record keeping information in
particular, and so I'd like to be able to tell if dereferencing a pointer
is going to crash my code or not before I do it, in a few strategic places.
Hence my above query.
Also, I'm going to be asking in come more general-purpose newsgroups, but
does anyone have any ideas about how to check pointers on other systems,
DOS and UNIX in particular?
Thanks for any help (or even idle flames, if I'm being particularly stupid :)
--
____________________________________________________________________________
Felix Potter potterf@lethe.uwa.edu.au
potterf@tartarus.uwa.edu.au
University of Western Australia, Perth. potter_f@cs.uwa.edu.au
+++++++++++++++++++++++++++
>From potterf@tartarus.uwa.edu.au (Felix Potter)
Date: 28 Mar 1994 06:58:21 GMT
Organization: The University of Western Australia
I (potterf@tartarus.uwa.edu.au), in a fit of stupidity, wrote:
> How does one check that a pointer is valid? (Without dereferencing it and
> possibly crashing the machine.) At the moment my definition for a pointer
> that is at least _possibly_ OK is:
> not null (ie. not equal to 0), and
> even (ie. not divisble by 2), and
^^^^ ^^^^^^^^^^^^^^^^^
Oops *blush* :)
Obviously I mean "divisible by 2."
--
____________________________________________________________________________
Felix Potter potterf@lethe.uwa.edu.au
potterf@tartarus.uwa.edu.au
University of Western Australia, Perth. potter_f@cs.uwa.edu.au
+++++++++++++++++++++++++++
>From Cameron Esfahani <dirty@guest.apple.com>
Date: Mon, 4 Apr 1994 04:42:50 GMT
Organization: Apple Computer, Inc.
In article <2n5uuu$ekq@styx.uwa.edu.au> Felix Potter,
potterf@tartarus.uwa.edu.au writes:
> How does one check that a pointer is valid? (Without dereferencing it and
> possibly crashing the machine.) At the moment my definition for a pointer
> that is at least _possibly_ OK is:
> not null (ie. not equal to 0), and
> even (ie. not divisble by 2), and
> > ApplZone (low memory global), and
> < ApplLimit (low memory global)
> So if my pointer fails one of these conditions, then I know straight away
> that something has gone wrong. Does anyone have any comments on either how
> reasonable or, on the other hand, how totally stupid the above description
is?
> Any suggestions for better ways of going about it?
>
> The reason I want to be able to check _quickly_ whether a pointer is valid
> or not is that I am writing a few little 'wrapper' macros/functions to
> go around the standard C malloc/calloc/realloc/free functions. I realise
that
> just about every man and his dog has done this before me, but hey, I'm
> having fun :) One of the things I would like to be able to do is detect
> heap corruption, and corruption of my record keeping information in
> particular, and so I'd like to be able to tell if dereferencing a pointer
> is going to crash my code or not before I do it, in a few strategic places.
> Hence my above query.
>
> Also, I'm going to be asking in come more general-purpose newsgroups, but
> does anyone have any ideas about how to check pointers on other systems,
> DOS and UNIX in particular?
>
> Thanks for any help (or even idle flames, if I'm being particularly stupid :)
Well, try installing your own Bus Error Handler and dereference
the pointer. If you get called in your Bus Error Handler, then it
is not a valid pointer. If you don't, it's valid....
Cameron Esfahani
dirty@apple.com
+++++++++++++++++++++++++++
>From ari@world.std.com (Ari I Halberstadt)
Date: Mon, 4 Apr 1994 06:26:22 GMT
Organization: The World Public Access UNIX, Brookline, MA
In article <2n5uuu$ekq@styx.uwa.edu.au>,
Felix Potter <potterf@tartarus.uwa.edu.au> wrote:
>How does one check that a pointer is valid? (Without dereferencing it and
>possibly crashing the machine.) At the moment my definition for a pointer
>that is at least _possibly_ OK is:
> not null (ie. not equal to 0), and
> even (ie. not divisble by 2), and
> > ApplZone (low memory global), and
> < ApplLimit (low memory global)
>So if my pointer fails one of these conditions, then I know straight away
>that something has gone wrong. Does anyone have any comments on either how
>reasonable or, on the other hand, how totally stupid the above description is?
>Any suggestions for better ways of going about it?
Those are most of the tests you'd ever need. If you get a crash from
dereferencing a pointer after doing those checks then I'd be pretty
surprised. If you didn't mind the speed hit, you could look for the
pointer in some private table of valid pointers, using some sort of
binary tree, for instance. What these tests don't tell you, however,
is whether the contents of the pointer are valid.
What I've done in my applications is create a header that is placed at
the start of every pointer allocated. The header contains the size of
the pointer and a 4-byte signature code. A unique signature code is
used for every type of object I allocate. Then I do something like
this:
ObjectPtr NewObject(...) {
ObjectPtr object = NewObjectPtr(sizeof(ObjectType), 'objp');
...
assert(ValidObject(object));
return(object);
}
Boolean ValidObject(ObjectPtr object) {
if (! ValidObjectPtr(object, sizeof(ObjectType), 'objp')) return(false);
... more tests to check relationships among members of the object ...
}
void DoSomethingToObject(ObjectPtr object) {
assert(ValidObject(object));
... use object ...
assert(ValidObject(object));
}
The function ValidObjectPtr compares the size and ID code passed to it
as parameters with the values stored in the pointer's header. If they
differ, then the pointer is deemed invalid and false is returned. The
function also checks that the pointer's header and the end of the
pointer are within the application's heap zone.
As a further enhancement, you could store a trailer at the end of each
pointer. The trailer would contain the same 4-byte id code, and would
help catch errors that resulted from overwriting the end of the
pointer.
Also, when you allocate a pointer, fill it with some random (or not so
random) garbage. Something like 0xff works pretty well and is easy to
spot with a debugger. Using an odd value like 0xff is also good since
any members of the object that are pointers will be detected as
illegal pointers (since they'll be odd integers). When you dispose of
the pointer, again fill it with 0xff, since this will ensure that you
won't be able to use its contents without immediate errors.
Alternatively, you could zero the pointer when you allocate it, thus
removing the need to initialize members to a default value. However,
you should still fill the pointer with invalid data when it is
disposed of. My personal preference is to zero program objects but to
fill data pointers with 0xff bits. I disable the filling of memory
with 0xff bits for greater efficiency in the final application
If you were really paranoid, you could checksum the contents of the
pointer. For instance, instead of just calling ValidObject, you could
do something like:
CheckInObject(object);
...
CheckOutObject(object);
CheckInObject would calculate a checksum for the object and compare it
with the checksum saved in the pointer's header. If the checksums
differ, CheckInObject would fail (e.g., raise an exception). Then, it
would call ValidObject, and finally it would increment a counter to
indicate that the object had been checksummed and is in use. A value
greater than zero for the counter would prevent further calls to
CheckInObject from calculating a checksum or calling ValidObject.
CheckOutObject would decrement the counter each time it is called.
When the matching call to CheckOutObject is made (the counter is zero)
then a new checksum would be calculated for the object and the
checksum would be stored in the pointer's header. This should be
reasonably efficient and quite robust. You could make CheckInObject
and CheckOutObject macros that you could undefine when debug code was
disabled, or could change the macros so that they didn't do the
checksum operation in the final product. I haven't used this method
yet in my own applications, but I'm thinking of adding it.
>
>The reason I want to be able to check _quickly_ whether a pointer is valid
>or not is that I am writing a few little 'wrapper' macros/functions to
>go around the standard C malloc/calloc/realloc/free functions. I realise that
>just about every man and his dog has done this before me, but hey, I'm
>having fun :) One of the things I would like to be able to do is detect
>heap corruption, and corruption of my record keeping information in
>particular, and so I'd like to be able to tell if dereferencing a pointer
>is going to crash my code or not before I do it, in a few strategic places.
>Hence my above query.
To check the heap, you can just use MacsBug or TMON with heap check
enabled. It works pretty well for most things. With TMON, one problem
is that by the time the heap is corrupted you can't figure out where
it failed in your code since all of the function labels are gone (it's
kind of a pain to get around this problem).
I like to validate memory on several different levels. The most
secure, but slowest, level is used during development. Less checks are
done in a beta level, and most (or all) checks are disabled in a
release version. However, lately, my memory checks have been fairly
fast (they used to be really slow), so I'm thinking of leaving at
least some of them in the release level.
Just checking the validity of pointers before calling memory
allocation and disposal routines is better than nothing, but overall
is not very secure. A pointer can easily become corrupted long before
free is ever called on it. You can also do a lot of extra verification
if you provide type information (like a four-byte code) in your code.
If you get fancy, you can even check the logical relationships among
the members of your objects. Checking logical relationships helps
catch additional programmatic errors.
>Also, I'm going to be asking in come more general-purpose newsgroups, but
>does anyone have any ideas about how to check pointers on other systems,
>DOS and UNIX in particular?
All of the checks I described above can be used on Unix systems. You
might have trouble finding something equivalent to ApplZone/ApplLimit
on Unix, but there's probably some equivalent, even if it's not
totally portable. The checks should probably also work with DOS
systems. The interpretation of multiple byte character constants is
not defined by the language, so things like 'objp' may have to be
modified (e.g., use defines in some common memory header, don't
scatter the constants all over the place).
--
Ari Halberstadt ari@world.std.com #include <std/disclaimer.h>
"These beetles were long considered to be very rare because very few
entomologists look for beetles in the mountains, in winter, at night,
during snow storms." -- Purves W. K., et al, "Life: The Science of
+++++++++++++++++++++++++++
>From Alexander M. Rosenberg <alexr@apple.com>
Date: Mon, 4 Apr 1994 12:39:22 GMT
Organization: Hackers Anonymous
In article <1994Apr4.044250.27756@gallant.apple.com> Cameron Esfahani,
dirty@guest.apple.com writes:
> Well, try installing your own Bus Error Handler and dereference
> the pointer. If you get called in your Bus Error Handler, then it
> is not a valid pointer. If you don't, it's valid....
Trouble-maker.
- -------------------------------------------------------------------------
- Alexander M. Rosenberg - INTERNET: alexr@apple.com - Yoyodyne -
- 330 Waverley St., Apt B - UUCP:ucbvax!apple!alexr - Propulsion -
- Palo Alto, CA 94301 - - Systems -
- (415) 329-8463 - Nobody is my employer so - :-) -
- - nobody cares what I say. - -
+++++++++++++++++++++++++++
>From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
Date: 5 Apr 94 05:34:57 GMT
Organization: University of Illinois at Urbana
ari@world.std.com (Ari I Halberstadt) writes:
>What I've done in my applications...
Ari offers some good suggestions. I once saw most of his suggestions
implemented in a library that was published in MacTech (MacTutor?) a while
back. I can't remember the name of the article, but I remember the library
functioned on the principle of wrapping accesses to your data with MMUse and
MMUnuse. The idea being that you had to call MMUse to be able to use your
data and must call MMUnuse as soon as you were done with it at that point.
This allowed for all kinds of nifty things the library could do behind your
back, like checksumming, checking for leaks, and even some primitive virtual
memory techniques. If I could remember the names of the authors, I'd cite
them for you.
(Was it 'MemMan'?)
--
Jim Browne | jbrowne@ncsa.uiuc.edu |
Head NCSA Mac Telnet Hacker, SDG System Administrator | (217) 244-7798 |
<a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
"Not me, not yet, not that bad."
+++++++++++++++++++++++++++
>From jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne)
Date: 5 Apr 94 07:28:00 GMT
Organization: University of Illinois at Urbana
jbrowne@zaphod.ncsa.uiuc.edu (Jim Browne) writes:
>ari@world.std.com (Ari I Halberstadt) writes:
>>What I've done in my applications...
>Ari offers some good suggestions. I once saw most of his suggestions
>implemented in a library that was published in MacTech (MacTutor?) a while
>back. I can't remember the name of the article, but I remember the library
>functioned on the principle of wrapping accesses to your data with MMUse and
>MMUnuse. The idea being that you had to call MMUse to be able to use your
>data and must call MMUnuse as soon as you were done with it at that point.
>This allowed for all kinds of nifty things the library could do behind your
>back, like checksumming, checking for leaks, and even some primitive virtual
>memory techniques. If I could remember the names of the authors, I'd cite
>them for you.
Well, I've gone and looked up the article. Thanks to those great people at
MacTech, I was able to grep the text index of articles for MacTech vols. 1-8.
Here's the reference:
"A Memory Manager for the Rest of US." by Jordan Zimmerman. Vol. 7 No. 9 Pg. 40
--
Jim Browne | jbrowne@ncsa.uiuc.edu |
Head NCSA Mac Telnet Hacker, SDG System Administrator | (217) 244-7798 |
<a href="http://www.ncsa.uiuc.edu/SDG/People/jbrowne/jbrowne.html">Click me</a>
--"It's really weird... kind of like how Telnet is programmed." - Q. Koziol --
---------------------------
>From Ben J Fry <bf2c+@andrew.cmu.edu>
Subject: textedit bounds
Date: Tue, 5 Apr 1994 21:15:13 -0400
Organization: Freshman, Design, Carnegie Mellon, Pittsburgh, PA
does anyone know how to figure out the real boundaries for a styled
textedit field? that is, the natural boundary rectangle that the text
would fit in...
any help would be really appreciated.. i've nearly worn out my think
reference in trying to look for this... (if that's possible...)
ben
+++++++++++++++++++++++++++
>From ari@world.std.com (Ari I Halberstadt)
Date: Wed, 6 Apr 1994 21:27:41 GMT
Organization: The World Public Access UNIX, Brookline, MA
In article <MhcUoV200iV8IC9nE_@andrew.cmu.edu>,
Ben J Fry <bf2c+@andrew.cmu.edu> wrote:
>does anyone know how to figure out the real boundaries for a styled
>textedit field? that is, the natural boundary rectangle that the text
>would fit in...
>
>any help would be really appreciated.. i've nearly worn out my think
>reference in trying to look for this... (if that's possible...)
>
>
>ben
Assuming you have word wrap turned on, you can find the width of the
text from the width of the destination rectangle. You can get the
height of the text with TEGetHeight. If you don't have word wrap
turned on, then you can either assume some maximum width, say 72
inches (5184 pixels). This is a large enough value to ensure that the
user can view most text, without making the horizontal scroll bar
as useless as a value of 32767 would. If you really want to be
accurate, then you you can calculate the width of the widest line in
the text. Here's some code to do this for both styled and unstyled
text. It knows way too much about TextEdit internals, but hey, it
works :-)
A few utility functions:
typedef unsigned long TicksType;
typedef SignedByte HandleStateType;
HandleStateType HandleLock(void *h)
{
HandleStateType state;
state = HGetState(h);
HLock(h);
return(state);
}
void HandleStateSet(void *h, HandleStateType state)
{
HSetState(h, state);
}
// word wrap macros
#define TEWrap(te) ((**(te)).crOnly >= 0)
#define TEWrapSet(wrap, te) ((void) ((**(te)).crOnly = ((wrap) ? 1 : -1)))
static Boolean TEOldStyle(TEHandle te)
{
return((**te).txSize != -1);
}
/* Calculate the width of the widest line in the line range. If the
operation takes longer than 'timeout' ticks to compute, then the
last line reached is returned in 'finalLine', and the result of
the function is the width of the widest line between 'firstLine'
and 'finalLine'. Otherwise (i.e., no timeout), the result of the
function is the width of the widest line and 'finalLine' is equal
to 'lastLine'.
The time out is provided since calculating the widths of the lines--
especially for long styled text documents--can take quite a while, and
doing so every time the document changes could be prohibitively slow.
Instead, if 'finalLine' is less than 'lastLine', then after processing some
events, the application can continue to call this function, passing
the value of 'finalLine' as the 'firstLine' parameter, until 'finalLine'
is equal to 'lastLine', at which point the maximum of the values returned
by the successive calls to this function will be the width of the widest
line in the original line range. */
static short TEWidthUnstyled(short firstLine, short lastLine,
TicksType timeout, long *finalLine, TEHandle te)
{
HandleStateType svTextHandleState; /* saved state of handle to text */
GrafPtr svPort; /* saved graf port */
Ptr textPtr; /* pointer to text */
short textWidth; /* width of text */
short lineIndex; /* current line number */
short lineLongest; /* length of longest line */
short lineStart; /* first character of line */
short lineEnd; /* last character of line */
long startTicks /* time when we started */
short txFont, txSize, txFace; /* saved text state */
require(TEOldStyle(te));
/* quick out */
if ((**te).nLines == 0) return(0);
/* keep track of elapsed time */
startTicks = TickCount();
/* find longest line */
lineStart = lineEnd = lineLongest = 0;
for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
/* remember length of longest line encountered so far */
if (lineLongest < (**te).lineStarts[lineIndex + 1] - (**te).lineStarts[lineIndex]) {
lineStart = (**te).lineStarts[lineIndex];
lineEnd = (**te).lineStarts[lineIndex + 1];
lineLongest = lineEnd - lineStart;
}
/* stop if took too long */
if (TickCount() - startTicks > timeout)
break;
}
/* calculate width of longest line */
GetPort(&svPort);
SetPort((**te).inPort);
txFont = (**te).inPort->txFont;
txSize = (**te).inPort->txSize;
txFace = (**te).inPort->txFace;
TextFont((**te).txFont);
TextSize((**te).txSize);
TextFace((**te).txFace);
svTextHandleState = HandleLock((**te).hText);
textPtr = *(**te).hText;
textWidth = TextWidth(textPtr, lineStart, lineEnd - lineStart);
HandleStateSet((**te).hText, svTextHandleState);
TextFont(txFont);
TextSize(txSize);
TextFace(txFace);
SetPort(svPort);
*finalLine = lineIndex;
return(textWidth);
}
/* see description of TEWidthUnstyled */
static short TEWidthStyled(short firstLine, short lastLine, TicksType timeout,
long *finalLine, TEHandle te)
{
HandleStateType svTextHandleState; /* saved state of handle to text */
HandleStateType svStyleHandleState; /* saved state of handle to style record */
HandleStateType svStyleTableState; /* saved state of handle to style table */
GrafPtr svPort; /* saved graf port */
TEStylePtr stylePtr; /* text's style record */
STPtr styleTable; /* text's style table */
StyleRun *runPtr; /* style runs array */
short runStart; /* start of next style run */
Ptr textPtr; /* pointer to text */
short textLength; /* length of text run */
short textWidth; /* width of text */
short lineWidth; /* width of current line */
short lineIndex; /* current line number */
short lineStart; /* first character of line */
short lineEnd; /* last character of line */
long startTicks; /* time when we started */
short txFont, txSize, txFace; /* saved text state */
require(! TEOldStyle(te));
/* quick out */
if ((**te).nLines == 0) return(0);
/* keep track of elapsed time */
startTicks = TickCount();
/* setup port */
GetPort(&svPort);
SetPort((**te).inPort);
txFont = (**te).inPort->txFont;
txSize = (**te).inPort->txSize;
txFace = (**te).inPort->txFace;
/* lock and dereference handles */
svTextHandleState = HandleLock((**te).hText);
textPtr = *(**te).hText;
svStyleHandleState = HandleLock(GetStylHandle(te));
stylePtr = *GetStylHandle(te);
svStyleTableState = HandleLock(stylePtr->styleTab);
styleTable = *stylePtr->styleTab;
/* initialize loop */
textWidth = 0;
runPtr = stylePtr->runs;
runStart = runPtr[1].startChar;
TextFont(styleTable[runPtr->styleIndex].stFont);
TextFace(styleTable[runPtr->styleIndex].stFace);
TextSize(styleTable[runPtr->styleIndex].stSize);
/* calculate widths of all lines */
for (lineIndex = firstLine; lineIndex < lastLine; lineIndex++) {
/* calculate width of line */
lineWidth = 0;
lineStart = (**te).lineStarts[lineIndex];
lineEnd = (**te).lineStarts[lineIndex + 1];
while (lineStart < lineEnd) {
if (lineStart == runStart) {
/* use next style run (assumes run array is sorted by startChar) */
runPtr++;
runStart = runPtr[1].startChar;
check(runPtr->startChar == lineStart);
TextFont(styleTable[runPtr->styleIndex].stFont);
TextFace(styleTable[runPtr->styleIndex].stFace);
TextSize(styleTable[runPtr->styleIndex].stSize);
}
/* calculate width of style run */
check(lineStart < runStart);
textLength = min(lineEnd - lineStart, runStart - lineStart);
check(textLength >= 1);
lineWidth += TextWidth(textPtr, lineStart, textLength);
lineStart += textLength;
}
textWidth = max(textWidth, lineWidth);
/* stop if took too long */
if (TickCount() - startTicks > timeout)
break;
}
/* restore saved state */
HandleStateSet(RecoverHandle((Ptr) styleTable), svStyleTableState);
HandleStateSet(RecoverHandle((Ptr) stylePtr), svStyleHandleState);
HandleStateSet(RecoverHandle((Ptr) textPtr), svTextHandleState);
TextFont(txFont);
TextSize(txSize);
TextFace(txFace);
SetPort(svPort);
*finalLine = lineIndex;
return(textWidth);
}
/* see description of TEWidthUnstyled */
short TEWidthTimeout(short start, short end,
TicksType timeout, long *final, TEHandle te)
{
return(TEOldStyle(te) ? TEWidthUnstyled(start, end, timeout, final, te) :
TEWidthStyled(start, end, timeout, final, te));
}
/* calculate the width of the widest line in the line range */
short TEWidth(short start, short end, TEHandle te)
{
return(TEWidthTimeout(start, end, LONG_MAX, 0, te));
}
--
Ari Halberstadt ari@world.std.com #include <std/disclaimer.h>
"These beetles were long considered to be very rare because very few
entomologists look for beetles in the mountains, in winter, at night,
during snow storms." -- Purves W. K., et al, "Life: The Science of
---------------------------
End of C.S.M.P. Digest
**********************